# encoding: utf-8
import requests, datetime

from .models import LoginToken
from app.extensions import log, ZenTao, db

from flask_restplus import Resource, fields
from app.extensions.api import Namespace, abort, http_exceptions
from . import parameters, schemas
from app.modules.user.models import User
from app.modules.role.models import Role
from app.modules.common.utils import GetMD5, GetTokenId, DbCommit, checkToken
from app.modules.common.schemas import BaseSchema
from flask import request

api = Namespace('login', description = "The interface for login operation")  # pylint: disable=invalid-name


@api.route('/')
class Login(Resource):
    @api.parameters(parameters.LoginParameters())
    @api.response(schemas.LoginSchema(many = False))
    def get(self, args):
        """
        do login
        :param args:
        :return:
        """
        log.info("============== start login ==============")
        _user_name = args['user_name']
        _user_pass = args['user_pass']
        _user = User.query.filter_by(account = _user_name).first()
        if _user is None:
            _msg = "start login , user %s is not exist " % _user_name
            log.error("============== %s ==============" % _msg)
            return {'success': False, 'msg': _msg}
        else:
            if str(_user.password) != str(GetMD5(_user_pass)):
                _msg = "start login , user %s password is error " % _user_name
                log.error("============== %s ==============" % _msg)
                return {'success': False, 'msg': _msg}
            else:
                _now = datetime.datetime.now()
                _token = LoginToken(GetTokenId(), _user.id, _user.account, _now, None, login_ip = request.remote_addr)
                db.session.add(_token)
                _rtn = DbCommit()
                if _rtn['success']:
                    return {'success': True, 'msg': 'user %s login success' % _user_name, 'data': _token.to_dict()}
                else:
                    return _rtn


@api.route('/status')
class Status(Resource):
    @api.parameters(parameters.LoginStatusParameters())
    @api.response(schemas.LoginSchema(many = False))
    @checkToken
    def get(self, args):
        """
        query user last login status
        :param args:
        :return:
        """
        log.info("============== start query login status ==============")
        _user_id = args['user_id']
        _user = User.query.filter_by(id = _user_id).first()
        if _user is None:
            _msg = "query login status , user %s is not exist" % _user_id
            log.info("==============  %s ============== " % _msg)
            return {'success': False, 'msg': _msg}
        else:
            _token = LoginToken.query.filter_by(user_id = _user_id).order_by(LoginToken.create_time.desc()).first()
            if _token is None:
                _msg = "query login status , user %s is never login" % _user_id
                log.info("==============  %s ============== " % _msg)
                return {'success': False, 'msg': _msg}
            else:
                return {'success': True, 'msg': '', 'data': _token.to_dict()}


@api.route('/info')
class LoginInfo(Resource):
    @api.parameters(parameters.LoginUserInfoParameters())
    @api.response(schemas.LoginInfoSchema(many = False))
    @checkToken
    def get(self, args):
        """
        query login user info
        :param args:
        :return:
        """
        log.info("============== start query login user info ==============")
        _token_id = args['token_id']
        _token = LoginToken.query.filter_by(token_id = _token_id, login_out_time = None).first()
        if _token is None:
            _msg = " %s is not login" % _token_id
            log.info("============== %s ==============" % _msg)
            return {'success': False, 'msg': _msg}
        else:
            _user = User.query.filter_by(id = _token.user_id).first()
            if _user is None:
                _msg = " %s user is not exist" % _token_id
                log.info("============== %s ==============" % _msg)
                return {'success': False, 'msg': _msg}
            else:
                _roles = str(_user.role).split("|")
                _role_list = []
                for _role_id in _roles:
                    if _role_id != '':
                        _role_list.append(Role.query.filter_by(role_id = _role_id).first())
                _user.role_list = _role_list
                _user.login_ip = _token.login_ip
                return {'success': True, 'msg': '', 'data': _user}


@api.route('/login_out')
class LoginOut(Resource):
    @api.parameters(parameters.LoginUserInfoParameters())
    @api.response(BaseSchema(many = False))
    @checkToken
    def get(self, args):
        """
        login out
        :param args:
        :return:
        """
        log.info("============== start login out ==============")
        _token_id = args['token_id']
        _token = LoginToken.query.filter_by(token_id = _token_id, login_out_time = None).first()
        if _token is None:
            _msg = " %s is not login" % _token_id
            log.info("============== %s ==============" % _msg)
            return {'success': False, 'msg': _msg}
        else:
            _token.login_out_time = datetime.datetime.now()
            return DbCommit()


@api.route('/sendMsgTest')
class SendMsgTest(Resource):
    @api.parameters(parameters.LoginUserInfoParameters())
    @api.response(BaseSchema(many = False))
    @checkToken
    def get(self, args):
        """
        send socket msg test
        :param args:
        :return:
        """
        log.info("============== send socket msg test ==============")
        from app.modules.notify.notifier import send_message
        _data = {'tt': '1', 'aa': 'aass'}
        from app.modules.notify.models import NotifyModel
        send_message(NotifyModel('stat', _data))
        return {'success': False, 'msg': ''}
